#include "q_io.h"
#include "pamet.h"
#include "lex_an.h"
#include "synt_an.h"
#include "jadro.h"
#include "qconst.h"
#include "unikat.h"
#include <stdlib.h>

//#define NODUPL	1

int Brbstromy=0;

char* aktsoubor;

static Qhrana *opravl=NULL,*opravp=NULL;
static Qpodminka *opodm=NULL;

static Qpodminka* sa_podminka(Lseznam* ls,Lseznam** de);
static Qpodminka* sa_disjunkce(Lseznam* ls,Lseznam** de);

static Ustrom ustrom;

/*static Qstrom* novystrom(char* o,int k,int)
{
  Qstrom* s=new Qstrom(o,k);
  if(t==2) ustrom.unikat(s);
  return s;
}

/*static Qstrom* novystrom(Qstrom* a,int)
{
  Qstrom* s=new Qstrom(a);
  //if(t==2) ustrom.unikat(s);
  return s;
}/**/

static inline int atom(Lseznam* l)
{
  return (l->tag()==_Latom);
}

static inline int atomovapromenna(Lseznam* l)
{
  return (l->tag()==_Latomovapromenna);
}

static inline int stromovapromenna(Lseznam* l)
{
  return (l->tag()==_Lstromovapromenna);
}

static inline int seznamovapromenna(Lseznam* l)
{
  return (l->tag()==_Lseznamovapromenna);
}

static Qpodminka* malopametipodm(Qpodminka* qp)
{
  malopameti(qp);
  return qp;
}

static Qpravidlo* malopametiprav(Qpravidlo* qp)
{
  malopameti(qp);
  return qp;
}

static int inv;
//static int test_pravidla(Qhrana* ql,Qhrana* qp,Lseznam* ls);
static Lanstav* lanstav;

void schyba(char* s,Lseznam* ls)
{
  if(ls)
    QERR<<STR_SYNTAXERROR<<" ("<<ls->radek()<<"/"<<ls->sloupec()<<"): "<<s<<endln;
  else QERR<<STR_SYNTAXERROR<<": "<<STR_UNEXPECTEDEOF;
  exit(1);
}

void svarovani(char* s,Lseznam* ls)
{
  if(ls)
    QERR<<STR_WARNING<<" ("<<ls->radek()<<"/"<<ls->sloupec()<<"): "<<s<<endln;
  else QERR<<STR_SYNTAXERROR<<": "<<STR_UNEXPECTEDEOF;
//  exit(1);
}

static Lseznam* dalsislovo(Lseznam* ls,int typ) // 1-program,2-vstup
{
  Lseznam* d;
  if(typ==1) d=lanstav->nacti_slovo_programu();
  else d=lanstav->nacti_slovo_vstupu();
  delete ls;
  return d;
}

/*static Lseznam* dalsislovovstupu(Lseznam* ls)
{
  Lseznam* d=lanstav->nacti_slovo_vstupu();
  delete ls;
  return d;
}

static Lseznam* dalsislovoprogramu(Lseznam* ls)
{
  Lseznam* d=lanstav->nacti_slovo_programu();
  delete ls;
  return d;
}/**/

static Qstrom* sa_atom(Lseznam* ls,Lseznam** dd,int typ)
{
  if(ls && (atom(ls) || atomovapromenna(ls)))
  {
    Qstrom* qs=new Qstrom(ls->obsah(),ls->tag());
    malopameti(qs);
    *dd=dalsislovo(ls,typ);
    return qs;
  }
  //QIO<<ls->tag();
  schyba(STR_ATOMEXPECTED,ls);
  return NULL;
}

static Qstrom* sa_strom(Lseznam* ls,Lseznam** dd,int typ);

static Qstrom* sa_stromel(Lseznam* ls,Lseznam** dd,int typ)
{
  if(ls && seznamovapromenna(ls))
  {
    Qstrom* qs=new Qstrom(ls->obsah(),ls->tag());
    malopameti(qs);
    *dd=dalsislovo(ls,typ);
    return qs;
  } else return sa_strom(ls,dd,typ);
}

static Qstrom* sa_strom(Lseznam* ls,Lseznam** dd,int typ)
{
  if(ls && stromovapromenna(ls))
  {
    Qstrom* qs=new Qstrom(ls->obsah(),ls->tag());
    malopameti(qs);
    *dd=dalsislovo(ls,typ);
    return qs;
  }
  Qstrom* ko=sa_atom(ls,dd,typ);
  if(!ko) return NULL;
  //ustrom.unikat(ko);
  if((*dd)->tag()==_Llevazavorka)
  {
   do {
    *dd=dalsislovo(*dd,typ);
    if((*dd)->tag()!=_Lnul)
    {
      Qstrom* s;
      if((*dd)->tag()==_Ldekompozice)
      {
	*dd=dalsislovo(*dd,typ);
	Qstrom* a=sa_atom(*dd,dd,typ);
	if(!a) { delete ko; return NULL; } // added on March 10th (PH)
	s=new Qstrom(a);
	malopameti(s);
      } else s=sa_stromel(*dd,dd,typ);
      if(!s) { delete ko; return NULL; }
      if(!ko->vsyn()) { ko->nsyn(s); /*ko->nsyn2(s);*/ }
      else {
	Qstrom* qs=ko->vsyn();
	while(qs->vbratr()) qs=qs->vbratr();
	qs->nbratr(s);
      }
    } else *dd=dalsislovo(*dd,typ);
   } while((*dd)->tag()==_Lcarka);
   if((*dd)->tag()!=_Lpravazavorka) { delete ko; schyba(STR_SIGNEXPECTED_RBRACKET,*dd); return NULL; }
   (*dd)=dalsislovo(*dd,typ);
  }
  return ko;
}

static Qhrana* sa_retez(Lseznam* ls,Lseznam** dd,int typ)
{
  Qstrom* s1=sa_strom(ls,dd,typ);
  if(!s1) return NULL; // added on March 10th (PH)
  Qhrana* u1=new Qhrana(s1);
  malopameti(u1);
  if(*dd && (*dd)->tag()==_Lplus)
  {
    *dd=dalsislovo(*dd,typ);
    Qhrana* u2=sa_retez(*dd,dd,typ);
    if(!u2) { delete u1; return NULL; } // added on March 10th (PH)
    u1->nretez1(u2);
    u2->nretez2(u1);
  }
  return u1;
}

static Qstrom* sa_seznam(Lseznam* ls,Lseznam** dd,int typ)
{
  Qstrom *u1,*u2=NULL;
  if(ls && seznamovapromenna(ls))
  {
    u1=new Qstrom(ls->obsah(),ls->tag());
    malopameti(u1);
    *dd=dalsislovo(ls,typ);
    //return qs;
  } else if(ls->tag()==_Lnul)
  { u1=new Qstrom((char*)NULL,_Lnul);
    malopameti(u1);
    *dd=dalsislovo(ls,typ); }
  else if(ls->tag()==_Ldekompozice)
  { ls=dalsislovo(ls,typ);
    Qstrom* a=sa_atom(ls,dd,typ);
    if(!a) return NULL; // added on March 10th (PH)
    u1=new Qstrom(a);
    malopameti(u1); }
  else u1=sa_strom(ls,dd,typ);
  if(!u1) return NULL; // added on March 10th (PH)
  if(*dd && (*dd)->tag()==_Lcarka)
  {
    *dd=dalsislovo(*dd,typ);
    u2=sa_seznam(*dd,dd,typ);
    if(!u2) { delete u1; return NULL; }
    if(u2->neprazdny()) u1->nbratr(u2);//opravicka
    //if(u1->neprazdny()) u2->nbratr2(u1);//opravicka
  }
  return (u1->neprazdny() || !u2 || !u2->neprazdny() ? u1 : u2);
}

Qpodminka* sa_podminka2(Lseznam* ls,Lseznam** dd)
{
  if(ls && ls->tag()==_Lkopie)
  {
    if(!opodm) { schyba(STR_CANNOTUSECOPYOP,ls); return NULL; }
    opodm->pocplus();
    *dd=dalsislovo(ls,1);
    return opodm;
  }
  if(ls && ls->tag()==_Llevapodmzavorka)
  {
    ls=dalsislovo(ls,1);
    Qpodminka* p=sa_disjunkce(ls,dd);
    if(!p) return NULL;
    if(*dd && (*dd)->tag()==_Lpravapodmzavorka)
    {
      *dd=dalsislovo(*dd,1);
      return p;
    } else { delete p; schyba(STR_SIGNEXPECTED_CRBRACKET,*dd); return NULL; }
  }
  Qstrom* u1=sa_seznam(ls,dd,1),*u2;
  if(!u1) return NULL;
  if(*dd)
  {
    switch((*dd)->tag())
    {
      case _Lrovnost:
	*dd=dalsislovo(*dd,1);
	u2=sa_seznam(*dd,dd,1);
	if(!u2) { delete u1; return NULL; }
	return malopametipodm(new Qrovnost(u1,u2));
      case _Lnerovnost:
	*dd=dalsislovo(*dd,1);
	u2=sa_seznam(*dd,dd,1);
	if(!u2) { delete u1; return NULL; }
	return malopametipodm(new Qnerovnost(u1,u2));
      case _Ldans:
	*dd=dalsislovo(*dd,1);
	u2=sa_seznam(*dd,dd,1);
	if(!u2) { delete u1; return NULL; }
	return malopametipodm(new Qdans(u1,u2));
      case _Lhors:
	*dd=dalsislovo(*dd,1);
	u2=sa_seznam(*dd,dd,1);
	if(!u2) { delete u1; return NULL; }
	return malopametipodm(new Qhors(u1,u2));
      default:
	delete u1;
	schyba(STR_SIGNEXPECTED_CONDOP,*dd);
	return NULL;
    }
  }
  return NULL;
}

Qpodminka* sa_negace(Lseznam* ls,Lseznam** dd)
{
  Qpodminka* p;
  if(ls && ls->tag()==_Lnon)
  {
    ls=dalsislovo(ls,1);
    p=sa_podminka2(ls,dd);
    if(!p) return NULL;
    return malopametipodm(new Qnegace(p));
  } else {
    p=sa_podminka2(ls,dd);
    if(!p) return NULL;
    return p;
  }
}

Qpodminka* sa_konjunkce(Lseznam* ls,Lseznam** dd)
{
  Qpodminka* p1=sa_negace(ls,dd);
  if(!p1) return NULL;
  if(*dd && (*dd)->tag()==_Let)
  {
    *dd=dalsislovo(*dd,1);
    Qpodminka* p2=sa_konjunkce(*dd,dd);
    if(!p2) { delete p1; return NULL; }
    return malopametipodm(new Qkonjunkce(p1,p2));
  } else return p1;
}

Qpodminka* sa_disjunkce(Lseznam* ls,Lseznam** dd)
{
  Qpodminka* p1=sa_konjunkce(ls,dd);
  if(!p1) return NULL;
  if(*dd && (*dd)->tag()==_Lou)
  {
    *dd=dalsislovo(*dd,1);
    Qpodminka* p2=sa_disjunkce(*dd,dd);
    if(!p2) { delete p1; return NULL; }
    return malopametipodm(new Qdisjunkce(p1,p2));
  } else return p1;
}

Qpodminka* sa_podminka(Lseznam* ls,Lseznam** dd)
{
  Qpodminka* p=sa_disjunkce(ls,dd);
  if(!p) return p;
  if(*dd && (*dd)->tag()==_Ltecka) { opodm=p; return p; }
  else { delete p; schyba(STR_SIGNEXPECTED_DOT,*dd); return NULL; }
}

Qpravidlo* sa_pravidlo(Lseznam* ls,Lseznam** dd)
{
  if(ls && ls->tag()==_Ldet)
  {
    svarovani(STR_DETIGNORED,ls);
    ls=dalsislovo(ls,1);
  }
  if(ls && ls->tag()==_Linv)
  {
    //svarovani(STR_INVNOTSTANDARD,ls);
    inv=!inv;
    ls=dalsislovo(ls,1);
  }
  if(ls && ls->tag()==_Ldet)
  {
    svarovani(STR_DETIGNORED,ls);
    ls=dalsislovo(ls,1);
  }
  Qhrana *l,*p;
/*  if(ls->radek()==81)
    puts(""); /* LADENI !!! */
  //QIO<<ls->tag();
  if(!ls) { schyba(STR_UNEXPECTEDEOF,ls); return NULL; }
  unsigned long rad1,slp1;
  rad1=ls->radek();
  slp1=ls->sloupec();
  if(ls->tag()==_Lkopie)
  {
    if(!opravl) { schyba(STR_CANNOTUSECOPYOP,ls); return NULL; }
    l=opravl;
    l->pocplus();
    *dd=dalsislovo(ls,1);
    //QERR<<(*dd)->tag()<<(*dd)->obsah();
  } else {
    l=sa_retez(ls,dd,1);
    if(!l) return NULL;
  }
  if((*dd)->tag()!=_Lprepis)
   { //if(ls) QIO<<ls->tag(); else QIO<<"NULL";
     schyba(STR_SIGNEXPECTED_DEQUAL,*dd); delete l; return NULL; }
  *dd=dalsislovo(*dd,1);
  if((*dd)->tag()==_Lkopie)
  {
    if(!opravp) { schyba(STR_CANNOTUSECOPYOP,*dd); return NULL; }
    p=opravp;
    p->pocplus();
    *dd=dalsislovo(*dd,1);
    //*dd=dalsislovo(*dd,1);
    //*de=(*de)->dal()->dal();
  } else {
    //*dd=dalsislovo(*dd,1);
    p=sa_retez(*dd,dd,1);
    if(!p) { delete l; return NULL; }
  }
  opravl=l; opravp=p;
  Qpodminka* podm=NULL;
  if(!*dd) { delete l; delete p; schyba(STR_SIGNEXPECTED_DOTSLASH,*dd); return NULL; }
  if((*dd)->tag()!=_Ltecka)
  {
    if((*dd)->tag()!=_Lpodminka) { delete l; delete p; schyba(STR_SIGNEXPECTED_DOTSLASH,*dd); return NULL; }
    *dd=dalsislovo(*dd,1);
    podm=sa_podminka(*dd,dd);
    if(!podm) { delete l; delete p; return NULL; }
    opodm=podm;
  }
  //Lseznam* ls2=*dd;
  unsigned long rad2,slp2;
  rad2=(*dd)->radek();
  slp2=(*dd)->sloupec();
  *dd=dalsislovo(*dd,1);
  //*de=(*de)->dal();
  if(!inv)
  {
    if(test_pravidla(l,p,podm,*dd)) return malopametiprav(new Qpravidlo(l,p,podm,aktsoubor,rad1,slp1,rad2,slp2));
    else return NULL;
  } else {
    if(test_pravidla(p,l,podm,*dd))
    return malopametiprav(new Qpravidlo(p,l,podm,aktsoubor,rad1,slp1,rad2,slp2));
    else return NULL;
  }
}

Qfaze* sa_faze(Lseznam* ls,Lseznam** dd)
{
  inv=0;
  Qpravidlo* f=sa_pravidlo(ls,dd),*g=f;
  if(!f) return NULL;
    /*QFILE.sethandle(stdout);
    f->test(NULL);/**/
  Qfaze* p=new Qfaze(f);
  malopameti(p);
  while((*dd) && (*dd)->tag()!=_Lreq)
  {
    Qpravidlo* h=sa_pravidlo(*dd,dd);
    if(!h) { delete f; return NULL; }
    /*QFILE.sethandle(stdout);
    h->test(NULL);/**/
    g->nastav(h); g=h;
  }
  return p;
}

Qprogram* sa_program(Lseznam* ls,Lseznam** dd)
{
  Qfaze* f=sa_faze(ls,dd),*g=f;
  if(!f) return NULL;
  Qprogram* p=new Qprogram(f);
  malopameti(p);
  while((*dd) && (*dd)->tag()==_Lreq)
  {
    *dd=dalsislovo(*dd,1);
    //*de=(*de)->dal();
    Qfaze* h=sa_faze(*dd,dd);
    if(!h) { delete f; return NULL; } // added on March 10th (PH)
    g->nastav(h); g=h;
  }
  return p;
}

Qprogram* synt_analyza(FILE* f)
{
  Lseznam *ls,*de;
  Lanstav st(f); lanstav=&st;
  ls=st.nacti_slovo_programu(); malopameti(ls);
  Qprogram* p=sa_program(ls,&de);
  if(!p) QERR<<STR_SYNTAXANALYSISFAILED<<" !!!"<<endln;
/*  while(ls)
  {
    de=ls->dal();
    delete ls;
    ls=de;
  }/**/
  //if(de) delete de;
  if(p) p->ocislovat(); // added on March 10th (PH)
  return p;
}

/*Qprogram* synt_analyza(Lseznam* ls)
{
  Lseznam* de;
  Qprogram* p=sa_program(ls,&de);
  if(!p) QERR<<STR_SYNTAXANALYSISFAILED<<" !!!"<<endln;
/*  while(ls)
  {
    de=ls->dal();
    delete ls;
    ls=de;
  }/**
  return p;
}/**/

Qhrana* sa_usek(Lseznam* ls,Lseznam** dal,Qhrana** posl,int* zac,int* kon)
{
  if(!ls || ls->tag()<_Lmaxtag) { schyba(STR_SIGNEXPECTED_NNN,ls); return NULL; }
  *zac=ls->tag()-_Lmaxtag;
  ls=dalsislovo(ls,2);
  Qstrom* qs=sa_strom(ls,&ls,2);
  if(!qs) return NULL; // added on March 10th (PH)
  if(Brbstromy) ustrom.unikat(qs);
  Qhrana* u1=new Qhrana(qs),*up=u1;
  malopameti(u1);
  while(ls && ls->tag()==_Lplus)
  {
    ls=dalsislovo(ls,2);
    Qstrom* qs=sa_strom(ls,&ls,2);
    if(!qs) { delete u1; return NULL; } // added on March 10th (PH)
    if(Brbstromy) ustrom.unikat(qs);
    Qhrana* u=new Qhrana(qs);
    malopameti(u);
    up->nretez1(u);
//    up->nbratr1(u);
    u->nretez2(up);
//    u->nbratr2(up);
    up=u;
  }
  if(!ls || ls->tag()<_Lmaxtag) { delete u1; schyba(STR_SIGNEXPECTED_NNN,ls); return NULL; }
  *kon=ls->tag()-_Lmaxtag;
  *posl=up;
  *dal=dalsislovo(ls,2);
  return u1;
}

Qhrana* synt_vstup2(Lseznam* ls,Lseznam** dd)
{
  struct Pom { Qhrana *u1,*u2; int zac,kon,spj; Pom* dal; };
  Pom* z=NULL,*p,*r;
  if(!ls || ls->tag()<_Lmaxtag)
  {
    schyba(STR_SIGNEXPECTED_NNN,ls);
    return NULL;
  }
  while(ls && ls->tag()>=_Lmaxtag)
  {
    Pom* u=new Pom;
    malopameti(u);
    u->spj=0;
    u->u1=sa_usek(ls,&ls,&u->u2,&u->zac,&u->kon);
    if(!u->u1) return NULL;
    if(!z)  p=z=u; else { p->dal=u; p=u; }
  }
  p->dal=NULL;
  *dd=ls;

  /*p=z; // Kontrolni vypis
  while(p)
  {
    fprintf(stderr, "-%d- ",p->zac);
    //p->u1->test(stderr);
    fprintf(stderr, " -%d-\n",p->kon);
    p=p->dal;
  } /**/

  //fprintf(stderr, "1");

  p=z;
  while(p)
  {
    r=z;
    while(r)
    {
      if(p->kon==r->zac) break;
      r=r->dal;
    }
    if(r) p->u2->nretez1(r->u1); //upravil OA
    p=p->dal;
  }

  //fprintf(stderr, "2");

  //pridal OA
  p=z;
  while(p)
  {
    r=z;
    while(r)
    {
      if(p->zac==r->kon) break;
      r=r->dal;
    }
    if(r) { p->u1->nretez2(r->u2); }
    p=p->dal;
  }/**/

  //fprintf(stderr, "3");

  p=z;
  while(p)
  {
    if(!p->spj)
    {
      int poc=p->zac;
      Qhrana* psl=p->u1;
      r=z;
      while(r)
      {
	if(p!=r && r->zac==poc)
	{
	  r->spj=1;
	  psl->nvetev1(r->u1);
	  psl=r->u1;
	}
	r=r->dal;
      }
    }
    p=p->dal;
  }

  //fprintf(stderr, "4");

  p=z;
  while(p) { p->spj=0; p=p->dal; }

  //fprintf(stderr, "5");

  p=z;
  while(p)
  {
    if(!p->spj)
    {
      int fin=p->kon;
      Qhrana* psl=p->u2;
      r=z;
      while(r)
      {
	if(p!=r && r->kon==fin)
	{
	  r->spj=1;
	  psl->nvetev2(r->u2);
	  psl=r->u2;
	}
	r=r->dal;
      }
    }
    p=p->dal;
  }

  //fprintf(stderr, "6");

  Qhrana* qr=z->u1;
  p=z;
  while(p) { r=p->dal; delete p; p=r; } /**/

  //fprintf(stderr, "7");

  return qr;
}

Qvstup* synt_vstup(FILE* f)
{
  Lanstav st(f); lanstav=&st;
  Lseznam* ls=st.nacti_slovo_vstupu(); malopameti(ls);
  Qhrana* qv=synt_vstup2(ls,&ls);
  if(!qv) { QERR<<STR_ENTRYSYNTAXANALYSISFAILED<<endln; return NULL; }
//  qv->test2(); puts("");
  Qvstup* vst=new Qvstup(qv,NULL,0); malopameti(vst);
  if(Brbstromy) vst->nunik(&ustrom);
  //Quzel* qp=qv;
  Qvstup* vst2=vst;
  do {
  //fprintf(stderr, "8a");
    if(!ls || ls->tag()==_Lzarazka) { if(ls) delete ls; return vst; }
  //fprintf(stderr, "8b");
//    if(!ls || ls->tag()!=_Latom && strcmp(ls->obsah(),"/")) { delete vst; schyba(STR_SIGNEXPECTED_SLASH,ls); return NULL; }
  //fprintf(stderr, "9");
    if(!ls || ls->tag()!=_Llomitko) { delete vst; schyba(STR_SIGNEXPECTED_SLASH,ls); return NULL; }
    ls=dalsislovo(ls,2);
    Qhrana* qa=synt_vstup2(ls,&ls);
  //fprintf(stderr, "-10");
    if(!qa) { delete vst; schyba(STR_ENTRYSYNTAXANALYSISFAILED,ls); return NULL; }
//    qa->test2(); puts("");
    Qvstup* vst3=new Qvstup(qa,NULL,0); malopameti(vst3);
  //fprintf(stderr, "-11");
    if(Brbstromy) vst3->nunik(&ustrom);
  //fprintf(stderr, "-12");
    vst2->ndalsi(vst3);
    vst2=vst3;
    //qp->nvstup(qa);
    //qp=qa;
  //fprintf(stderr, "-13");
  } while(1);
}

/*Quzel* synt_vstup(Lseznam* ls)
{
  Quzel* qv=synt_vstup2(ls,&ls);
  if(!qv) { schyba(STR_ENTRYSYNTAXANALYSISFAILED,ls); return NULL; }
//  qv->test2(); puts("");
  Quzel* qp=qv;
  do {
    if(!ls || ls->tag()==_Lzarazka) return qv;
    if(ls->tag()!=_Llomitko) { delete qv; schyba(STR_SIGNEXPECTED_SLASH,ls); return NULL; }
    ls=ls->dal();
    Quzel* qa=synt_vstup2(ls,&ls);
    if(!qa) { delete qv; schyba(STR_ENTRYSYNTAXANALYSISFAILED,ls); return NULL; }
//    qa->test2(); puts("");
    qp->nvstup(qa);
    qp=qa;
  } while(1);
}/**/


/*int test_pravidla(Qhrana* ql,Qhrana* qp,Lseznam* ls)
{
  class Prom
  {
    protected:
      char* jmeno; Prom* dal;
    public:
      Prom(char* j,Prom* d):jmeno(j),dal(d) {}
      ~Prom() { if(dal) delete dal; }
      int existuje(char* j)
      { if(!j && !jmeno || !stricmp(j,jmeno)) return 1;
	else if(dal) return dal->existuje(j); else return 0; }
  };
  Prom* prom=NULL;
  class Uzel
  {
    protected:
      Qhrana* qu;
      Uzel* dal;
    public:
      Quzel* vqu() { return qu; }
      Uzel(Quzel* q,Uzel* d):qu(q),dal(d) {}
      Uzel* vdal() { return dal; }
  };
  Uzel* u=new Uzel(ql,NULL);
  malopameti(u);
  while(u)
  {
    Uzel* v=u->vdal();
    if(u->vqu()->vkonst()) { prom=new Prom(u->vqu()->vobsah(),prom); malopameti(prom); }
    if(u->vqu()->vretez1()) { v=new Uzel(u->vqu()->vretez1(),v);  malopameti(v); }
    if(u->vqu()->vbratr1()) { v=new Uzel(u->vqu()->vbratr1(),v);   malopameti(v); }
    if(u->vqu()->vsyn1()) { v=new Uzel(u->vqu()->vsyn1(),v);  malopameti(v); }
    delete u;
    u=v;
  }
  u=new Uzel(qp,NULL);
  malopameti(u);
  while(u)
  {
    Uzel* v=u->vdal();
    Quzel* tqu=(!u->vqu()->vdesint() ? u->vqu() : u->vqu()->vdesint());
    if(tqu->vkonst() && !prom->existuje(tqu->vobsah()))
    { schyba(STR_UNKNOWNVAR,ls); return 0; }
    if(u->vqu()->vretez1()) { v=new Uzel(u->vqu()->vretez1(),v); malopameti(v); }
    if(u->vqu()->vbratr1()) { v=new Uzel(u->vqu()->vbratr1(),v); malopameti(v); }
    if(u->vqu()->vsyn1()) { v=new Uzel(u->vqu()->vsyn1(),v);  malopameti(v); }
    delete u;
    u=v;
  }
  delete prom;
  return 1;
}/**/
